home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / pdclk145.zip / PING.ASM < prev    next >
Assembly Source File  |  1992-10-03  |  17KB  |  780 lines

  1. ;        ping.asm
  2. ;========================================================================
  3.  
  4. ; Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.
  5.  
  6. MsgEchoHead    db    CR, LF, "Ping with packet size "
  7. MsgEchoSweep    db    " "
  8. MsgEchoSize    db    "0    and interval"
  9. MsgEchoMs    db    "     0 ms to "
  10. MsgEchoTarget    db    "1.2.3.4        :", CR, LF, LF
  11. MsgEchoStats    db    "───────── Packets ──────── ║ ────── Delay ms ────── ║   Packet  ║ Load ║  Time ", CR, LF
  12.         db    "transmit  receive     diff ║ this   min   avg   max ║    loss   ║ kb/s ║     s ", CR, LF, "$$"
  13. MsgEcho        db    "       0        0        0      0     0     0     0     0.0000 %     0       0 ", CR, '$'
  14.  
  15. MsgSerrTbl    dw    offset MsgSerrUnr
  16.         dw    offset MsgSerrObuf
  17.         dw    offset MsgSerrNoarp
  18.         dw    offset MsgSerrTimout
  19.         dw    offset MsgSerrNotraf
  20. SERRTABLEN      equ     $-MsgSerrTbl
  21.         dw    offset MsgSerrUnimpl
  22.  
  23. MsgSerrUnr    db    LF, "Host or net unreachable", CR, LF, '$'
  24. MsgSerrObuf    db    LF, "Temporary out of buffers", CR, LF, '$'
  25. MsgSerrNoarp    db    LF, "Got no ARP reply", CR, LF, '$'
  26. MsgSerrTimout    db    LF, "Timeout", CR, LF, '$'
  27. MsgSerrNotraf    db    LF, "Received no traffic from destination", CR, LF, '$'
  28.  
  29. MsgSerrUnimpl    db    LF, "Send Error.", CR, LF, '$'
  30.         even
  31. EchoTarget    dw    0, 0            ; echo argument values
  32. EchoSize    dw    32
  33. EchoInterval    dw    256
  34. EchoData    dw    101h
  35. EchoDataIncW    dw    1
  36.  
  37. EchoStart    dw    0, 0, 0            ; echo variables
  38. EchoNext    dw    0
  39. EchoLastDispl    dw    0
  40. EchoLastHi    dw       0
  41. EchoMaxSize    dw    1500
  42. EchoAvgSum    dw    0, 0
  43. EchoFudge    dw    0
  44. EchoLoad    dw    0, 0
  45. EchoPrevLoad    dw    0, 0
  46. EchoDrop    dw    0
  47. EchoLastErr    dw    0
  48. PingRowCnt    dw    17
  49. k55        dw    55
  50. k100        dw    100
  51. k220        dw    220
  52.  
  53. EchoTx32    dw    0, 0            ; echo display variables
  54. EchoRx32    dw    0, 0
  55. EchoDif     dw    0, 0
  56. EchoThis    dw    0
  57. EchoMin     dw    0ffffh
  58. EchoAvg     dw    0
  59. EchoMax     dw    0
  60. EchoLoss    dw    0, 0
  61. EchoElapsed    dw    0, 0
  62.  
  63.  
  64. ;************************************************************************
  65. ;*        EchoAwhile
  66. ;************************************************************************
  67.  
  68. MsgCalling    db    "Calling nameserver(s)... $"
  69. MsgNameRep    db    "got reply in "
  70. MsgNameRepTim    db    "     ms.", CR, LF, '$'
  71. MsgBadName    db    LF, "Bad hostname (or no nameserver).$"
  72.  
  73. EchoAwhile    proc    near
  74.                 cmp     EchoTarget,0            ; want to ping someone?
  75.                 jne     EchoYes
  76.                 ret
  77.   EchoYes:
  78.         call    InitTimer        ; prepare millisecond timing
  79.  
  80.         call    HardwareTicks
  81.         mov    EchoStart,si        ; note start ticks
  82.         mov    EchoStart+2,dx
  83.         mov    EchoStart+4,ax
  84.  
  85.         call    DblShrX
  86.         mov    EchoNext,ax
  87.  
  88.                 cmp     EchoTarget,127          ; dns lookup to do?
  89.                 jne     EchoIpAddr
  90.  
  91.         mov    dx,offset MsgCalling
  92.         mov    ah,9
  93.         int    21h
  94.  
  95.         mov    dx,2345h        ; ping udp src port
  96.         xor    ax,ax            ; NsId
  97.         mov    si,offset EchoNameBuf    ; Ns question string
  98.  
  99.         call    NsResolve        ; call nameserver(s)
  100.  
  101.         call    HardwareTicks        ; response time
  102.         sub    ax,EchoStart+4
  103.         sbb    dx,EchoStart+2
  104.         div    kTimerScale
  105.         mov    di,offset MsgNameRepTim
  106.         mov    PutNumFiller,' '
  107.         mov    PutMinDigits,4
  108.         call    PutNum
  109.  
  110.         mov    dx,offset MsgNameRep    ; display it.
  111.         mov    ah,9
  112.         int    21h
  113.  
  114.                 cmp     EchoTarget,127          ; name resolved?
  115.                 jne     EchoIpAddr
  116.  
  117.         mov    dx,offset MsgBadName
  118.         mov    ah,9
  119.         int    21h
  120.   EchoErrTerm:
  121.         mov    al,'e'-'0'
  122.         call    terminate
  123.   
  124.   EchoIpAddr:
  125.         test    ArgFlags,MAKE_TABLE
  126.         jz    EchoNotTbl
  127.         or    GenFlags,TBL_READY
  128.   EchoNotTbl:
  129.         mov    di,offset EchoSizeVec
  130.         mov    cx,(EchoSizeEnd-EchoSizeVec)/2
  131.         xor    ax,ax
  132.         rep    stosw
  133.  
  134.         test    ArgFlags,TERM_WAIT
  135.         jnz    EchoAsIs
  136.         cmp    EchoInterval,128
  137.         jge    EchoAsIs
  138.         mov    EchoInterval,128
  139.   EchoAsIs:
  140.         call    BufAlloc        ; get a send buf
  141.         jz    EchoErrTerm
  142.  
  143.         call    MakeSendDescr
  144.         mov    [di].uIcmpTypeCode,8    ; type = echo request
  145.         test    GenFlags,UDP_ECHO
  146.         jz    EchoUseIcmp
  147.  
  148.         mov    word ptr MsgEchoHead+2,'cE'
  149.         mov    word ptr MsgEchoHead+4,'oh'
  150.         mov    word ptr [di].uUdpSrc,0703h    ; my udp echo port
  151.         mov    word ptr [di].uUdpDst,0900h    ; dst discard port
  152.         test    ArgFlags,UDP_DISCARD
  153.         jnz    EchoUseIcmp
  154.         mov    word ptr [di].uUdpDst,0700h    ; dst echo port
  155.   EchoUseIcmp:
  156.         mov    cx,(1500-IPHDRLEN-ICMPHDRLEN-4)/2
  157.         add    di,ICMPHDRLEN+4
  158.         mov    ax,EchoData
  159.   EchoFillLoop:
  160.         stosw
  161.         add    ax,EchoDataIncW
  162.         loop    EchoFillLoop
  163.   EchoFillEnd:
  164.         mov    si,offset EchoTarget-iIpSrc
  165.         call    SwitchIpdstB        ; set IP destination
  166.  
  167.         mov    si,offset EchoTarget
  168.         mov    di,offset MsgEchoTarget
  169.         call    PutIpNum        ; tell who we are pinging
  170.  
  171.         mov    cx,EchoSize
  172.         or    cx,cx
  173.         jns    EchoSizePos
  174.         neg    cx
  175.         mov    MsgEchoSweep,'<'
  176.   EchoSizePos:
  177.         sub    cx,IPHDRLEN+ICMPHDRLEN+4
  178.         cmp    cx,GIANT-HWHDRLEN-IPHDRLEN-ICMPHDRLEN-4
  179.         jbe    EchoOkSize
  180.         xor    cx,cx
  181.   EchoOkSize:
  182.         mov    ax,cx
  183.         add    ax,IPHDRLEN+ICMPHDRLEN+4
  184.         mov    EchoSize,cx
  185.         mov    EchoMaxSize,cx
  186.  
  187.         mov    di,offset MsgEchoSize
  188.         mov    PutMinDigits,1
  189.         call    PutNum            ;   and the packet size used
  190.  
  191.         mov    ax,EchoInterval
  192.         mov    di,offset MsgEchoMs
  193.         mov    PutMinDigits,6
  194.         mov    PutNumFiller,' '
  195.         call    PutNum            ;   and interval in ms
  196.  
  197.         mov    dx,offset MsgEchoHead
  198.         mov    ah,9
  199.         int    21h            ; display it
  200.   EchoLoop0:
  201.         nop                ; (just to separate the loops)
  202.   EchoLoop:
  203.         call    Something2Do        ; process other things
  204.         jnz    EchoLoop        ; maybe more to do
  205.  
  206.         call    EchoDisplay        ; show current values
  207.  
  208.         call    AnyKey            ; first key stops sending
  209.         jz    EchoNoKey
  210. if 0
  211.         cmp    al,'y' and 01fh        ; ignore most control keys
  212.         jbe    EchoNoKey
  213. endif
  214.         jmp    EchoEnd
  215.   EchoNoKey:
  216.         cmp    FreeBufs.lBufsAvail,3*NBUFS/4
  217.         jle    EchoLoop        ; prevent buffer starving
  218.  
  219.         call    HardwareTicks
  220.         call    DblShrX
  221.         mov    dx,ax
  222.         sub    ax,EchoNext        ; time to send next echo pkt?
  223.         js    EchoLoop0
  224.  
  225.         add    dx,EchoInterval
  226.         mov    EchoNext,dx        ; next send time
  227.  
  228.         add    EchoTx32+2,1        ; increment send counters
  229.         adc    EchoTx32,0
  230.         mov    EchoFudge,1
  231.  
  232.         mov    cx,EchoSize        ; compute packet size
  233.         cmp    MsgEchoSweep,'<'
  234.         jne    EchoFillFixed
  235.         inc    cx
  236.         cmp    cx,EchoMaxSize
  237.         jbe    EchoFillSize
  238.         mov    cx,28-IPHDRLEN-ICMPHDRLEN
  239.   EchoFillSize:
  240.         mov    EchoSize,cx
  241.   EchoFillFixed:
  242.         add    cx,ICMPHDRLEN+4        ; IP data length
  243.  
  244.         mov    di,cx
  245.         shl    di,1
  246.         inc    word ptr EchoSizeVec[di]
  247.  
  248.         call    HardwareTicks        ; put timestamp
  249.         mov    di,[bx].dPtrUdp
  250.         mov    [di].uUdpData,ax
  251.         mov    [di].uUdpData+2,dx
  252.  
  253.         test    GenFlags,UDP_ECHO
  254.         jnz    EchoUdp
  255.         call    SendIcmpPkt        ; send icmp echo pkt
  256.   EchoLoop8:
  257.         jnz    EchoErr         ; any errors?
  258.   EchoLoop9:
  259.         mov    EchoLastErr,cx
  260.         jmp    EchoLoop
  261.  
  262.   EchoUdp:
  263.         mov    ax,cx
  264.         call    SendUdpPkt        ; send udp echo pkt
  265.         jmp    short EchoLoop8
  266.  
  267.   EchoErr:
  268.         cmp    cx,EchoLastErr
  269.         je    EchoLoop9
  270.  
  271.         push    cx
  272.         xor    ch,ch
  273.         cmp    cl,SERRTABLEN
  274.         jb    EchoErrExist
  275.         mov    cl,SERRTABLEN
  276.   EchoErrExist:
  277.         mov    si,cx
  278.         mov    dx,MsgSerrTbl[si]
  279.         mov    ah,9
  280.         int    21h            ; display send error
  281.         pop    cx
  282.                 test    ArgFlags,TERM_WAIT
  283.                 jnz     EchoLoop9
  284.  
  285.   EchoEnd:
  286.         call    BufRelease        ; release send buffer
  287.         mov    EchoFudge,0
  288.         or    ArgFlags,TERM_WAIT
  289.         ret
  290. EchoAwhile    endp
  291.  
  292.  
  293.  
  294. if DEBUG
  295.   TstBufLinks    proc    near
  296.         ja    TstErrEI
  297.         mov    si,di
  298.         inc    cx
  299.     TstLinkLoop:
  300.         mov    di,[di].dNext
  301.         mov    si,[si].dPrev
  302.         loop    TstLinkLoop
  303.         cmp    si,di
  304.         jne    TstErrEI
  305.         ret
  306.   TstBufLinks    endp
  307.  
  308.   TstErrEI:
  309.         PopfEI
  310.   TstErr:
  311.         push    bx
  312.         mov    bx,'>-'
  313.         push    bx
  314.         push    bx
  315.         call    terminate
  316. endif ; DEBUG
  317.  
  318.  
  319.  
  320. ;************************************************************************
  321. ;*        EchoDisplay
  322. ;************************************************************************
  323.  
  324.  
  325. EchoDisplay    proc    near
  326. if DEBUG
  327.         push    bx
  328.         mov    al,'s'-'0'
  329.         cmp    word ptr phd_dioa,0    ; stack overflowed?
  330.         jne    TstErr
  331.  
  332.         mov    al,'t'-'0'
  333.         cmp    word ptr StackLow,0    ; stack overflowed?
  334.         jne    TstErr
  335.  
  336.         mov    al,'i'-'0'
  337.         test    GenFlags,DBGINTERR    ; any interrupt debug errs?
  338.         jnz    TstErr
  339.  
  340.         mov    cx,NBUFS        ; any buffers damaged?
  341.         mov    bx,offset BufStart
  342.         mov    al,'u'-'0'
  343.   BufTestLoop:
  344.                 cmp     [bx].dHomeList,offset FreeBufs
  345.         jne    TstErr
  346.         add    bx,BUFSIZE
  347.         loop    BufTestLoop
  348.  
  349.         PushfDI
  350.         mov    di,offset FreeBufs
  351.         mov    cx,[di].lBufsAvail
  352.         cmp    cx,NBUFS
  353.         call    TstBufLinks
  354.         cmp    di,offset FreeBufs
  355.         jne    TstErrEI
  356.         PopfEI
  357.  
  358.                 mov     cx,NBUFSMALL
  359.         mov    al,'v'-'0'
  360.   TstSmlLoop:
  361.                 cmp     [bx].dHomeList,offset FreeSmal
  362.         jne    TstErr
  363.                 add     bx,BUFSIZESML
  364.                 loop    TstSmlLoop
  365.  
  366.         PushfDI
  367.         mov    di,offset FreeSmal
  368.         mov    cx,[di].lBufsAvail
  369.         cmp    cx,NBUFSMALL
  370.         call    TstBufLinks
  371.         cmp    di,offset FreeSmal
  372.         jne    TstErrEI
  373.         PopfEI
  374.         pop    bx
  375. endif ; DEBUG
  376. ; *test        cmp    EchoTarget,0        ; are we pinging?
  377. ;        je    EchoDispRet
  378.  
  379.         call    CurrentTicks
  380.         shr    cx,1
  381.         shr    cx,1
  382.         mov    ax,EchoLastDispl
  383.         shr    ax,1
  384.         shr    ax,1
  385.         cmp    ax,cx            ; time to update display?
  386.         jne    EchoDispNow
  387.   EchoDispRet:
  388.         ret
  389.  
  390.   EchoDispNow:
  391.         push    bx
  392.  
  393.         cli
  394.         mov    dx,EchoAvgSum
  395.         mov    ax,EchoAvgSum+2
  396.         mov    cx,EchoRx32
  397.         mov    bx,EchoRx32+2
  398.         sti
  399.         call    AdjTo16Bits
  400.         or    bx,bx            ; avoid div by zero
  401.         jz    EchoSkipAvg
  402.  
  403.         div    bx
  404.         mov    EchoAvg,ax        ; average delay
  405.   EchoSkipAvg:
  406.  
  407.         mov    dx,EchoTx32        ; compute difference tx - rx
  408.         mov    ax,EchoTx32+2
  409.         sub    ax,EchoFudge        ;   subtract one if just
  410.         sbb    dx,0            ;   sent a pkt
  411.         push    ax
  412.         push    dx
  413.         cli
  414.         sub    ax,EchoRx32+2
  415.         sbb    dx,EchoRx32
  416.         sti
  417.         jns    EchoDifPos        ; use abs(tx-rx)
  418.         not    ax
  419.         not    dx
  420.         add    ax,1
  421.         adc    dx,0
  422.   EchoDifPos:
  423.         mov    Echodif,dx
  424.         mov    Echodif+2,ax
  425.  
  426.         mov    cl,2            ; compute packet loss
  427.         call    DblShl            ;   multiply by 100
  428.         mov    si,dx
  429.         mov    bx,ax
  430.         mov    cl,3
  431.         call    DblShl
  432.         add    bx,ax
  433.         adc    si,dx
  434.         shl    ax,1
  435.         rcl    dx,1
  436.         add    ax,bx
  437.         adc    dx,si
  438.  
  439.         pop    cx
  440.         pop    bx
  441.  
  442.         call    AdjTo16Bits
  443.         or    bx,bx            ; avoid div by zero
  444.         jz    EchoSkipLoss
  445.  
  446.         div    bx
  447.         mov    EchoLoss,ax
  448.  
  449.         mov    ax,dx            ;   fractional loss
  450.         mul    k10000
  451.         div    bx
  452.         mov    EchoLoss+2,ax
  453.   EchoSkipLoss:
  454.         push    cs            ; edit echo values
  455.         pop    es
  456.  
  457.         mov    di,offset MsgEcho-1
  458.         mov    si,offset EchoTx32
  459.         mov    PutNumFiller,' '
  460.         mov    PutMinDigits,9
  461.         mov    cx,3
  462.         call    PutBigNums        ; tx and rx and diff
  463.  
  464.         mov    PutMinDigits,6
  465.         inc    di
  466.         mov    cx,5
  467.   EchoDispLoop:
  468.         push    cx
  469.         mov    cl,1
  470.         call    PutNums            ; delays and loss
  471.         pop    cx
  472.         loop    EchoDispLoop
  473.  
  474.         mov    PutNumFiller,'0'
  475.         inc    di
  476.         mov    cl,1
  477.         call    PutNumsD4        ; .0000%
  478.  
  479.         cli
  480.         mov    ax,EchoLoad+2
  481.         mov    bx,ax
  482.         mov    dx,EchoLoad
  483.         mov    cx,dx
  484.         add    ax,EchoPrevLoad+2
  485.         adc    dx,EchoPrevLoad
  486.         mov    EchoLoad+2,0
  487.         mov    EchoLoad,0
  488.         sti
  489.         mov    EchoPrevLoad+2,bx
  490.         mov    EchoPrevLoad,cx
  491.         div    k55            ; assumes clr every 2nd tick
  492.         add    di,4
  493.         mov    PutNumFiller,' '
  494.         call    PutNum            ; load kb/s
  495.  
  496.         call    HardwareTicks        ; compute elapsed time
  497.         mov    ax,dx
  498.         mov    dx,si
  499.         cmp    dx,EchoLastHi
  500.         jae    EchoLastGrows
  501.  
  502.         mov    bx,EchoLastDispl
  503.         mov    cx,EchoLastHi
  504.         sub    EchoStart+2,bx
  505.         sbb    EchoStart,cx
  506.   EchoLastGrows:
  507.         mov    EchoLastDispl,ax
  508.         mov    EchoLastHi,dx
  509.         sub    ax,EchoStart+2
  510.         sbb    dx,EchoStart
  511.         mov    cl,4            ; divide # of ticks by 18.2
  512.         call    DblShr
  513.         mov    EchoElapsed+2,ax
  514.         mov    EchoElapsed,dx
  515.         mov    cl,3
  516.         call    DblShr
  517.         sub    EchoElapsed+2,ax
  518.         sbb    EchoElapsed,dx
  519.         mov    cl,5
  520.         call    DblShr
  521.         add    ax,EchoElapsed+2
  522.         adc    dx,EchoElapsed
  523.         mov    PutNumFiller,' '
  524.         mov    PutMinDigits,8
  525.         call    PutBigNum        ; elapsed time
  526. if DEBUG
  527.         mov    dx,280h+10h        ; assume WD card at IO 280h
  528.         xor    ax,ax
  529.         xor    cx,cx
  530.         cli
  531.         out    dx,al            ; set page 0
  532.         call    IoDelay
  533.         add    dx,0dh
  534.         in    al,dx            ; readandclear frame err ctr
  535.         add    cx,ax
  536.         inc    dx
  537.         in    al,dx            ; readnadclear bad CRC ctr
  538.         add    cx,ax
  539.         inc    dx
  540.         in    al,dx            ; readandclear lost frames ctr
  541.         sti
  542.         add    cx,ax
  543.         add    EchoDrop,cx        ; add out of bufs ctr
  544. endif ; DEBUG
  545.         mov    ax,EchoDrop
  546. if DEBUG eq 0
  547.         or    ax,ax
  548.         jz    EchoNoDrops
  549. endif ; DEBUG eq 0
  550.         mov    di,offset MsgEcho+18    ; place before diff
  551.         mov    PutMinDigits,1
  552.         call    PutNum            ; show dropped packets
  553.   EchoNoDrops:
  554.         mov    dx,offset MsgEcho    ; display echo values
  555.         mov    ah,9
  556.         int    21h
  557.  
  558.         pop    bx
  559.         ret
  560. EchoDisplay    endp
  561.  
  562.  
  563.  
  564. ;************************************************************************
  565. ;*        AdjTo16Bits
  566. ;************************************************************************
  567.  
  568. AdjTo16Bits    proc    near
  569.   AdjTest:
  570.         or    cx,cx            ; fits in 16 bits?
  571.         jnz    Adjust
  572.         or    dx,dx
  573.         jnz    Adjust
  574.         ret
  575.   Adjust:
  576.         shr    dx,1            ; shift 32 bits right
  577.         rcr    ax,1
  578.         shr    cx,1
  579.         rcr    bx,1
  580.         jmp    short AdjTest
  581. AdjTo16Bits    endp
  582.  
  583.  
  584.  
  585. ;************************************************************************
  586. ;*        DblShrX
  587. ;************************************************************************
  588.  
  589. DblShrX     proc    near
  590.         mov    cx,7
  591.         test    ArgFlags,MICRO_100
  592.         jnz    DblShr
  593. DblShr10:
  594.         mov    cl,10
  595. DblShr:
  596.         xor    ch,ch
  597.   DblShrNext:
  598.         shr    dx,1            ; shift 32 bits right
  599.         rcr    ax,1
  600.         loop    DblShrNext
  601.         ret
  602. DblShrX     endp
  603.  
  604.  
  605.  
  606. ;************************************************************************
  607. ;*        DblShl
  608. ;************************************************************************
  609.  
  610. DblShl        proc    near
  611.         xor    ch,ch
  612.   DblShlNext:
  613.         shl    ax,1            ; shift 32 bits left
  614.         rcl    dx,1
  615.         loop    DblShlNext
  616.         ret
  617. DblShl        endp
  618.  
  619.  
  620.  
  621. ;************************************************************************
  622. ;*        EchoCalc
  623. ;************************************************************************
  624.  
  625.         even
  626. kTimerScale    dw    TimerResolution
  627.  
  628. EchoCalc    proc    near
  629.  
  630.         add    EchoRx32+2,1        ; increment receive counters
  631.         adc    EchoRx32,0
  632.         mov    EchoFudge,0
  633.  
  634.         mov    di,[bx].dPktLen        ; IP data length
  635.         shl    di,1
  636.         dec    word ptr EchoSizeVec[di]
  637.  
  638.         call    HardwareTicks        ; compute delay
  639.         mov    di,[bx].dPtrUdp
  640.         sub    ax,[di].uUdpData
  641.         sbb    dx,[di].uUdpData+2
  642.         js    EchoCalcRet
  643.         div    kTimerScale
  644.         mov    EchoThis,ax        ; delay for this packet
  645.  
  646.         add    EchoAvgSum+2,ax
  647.         adc    EchoAvgSum,0
  648.  
  649.         cmp    ax,EchoMin
  650.         jb    EchoSetMin
  651.   EchoChkMax:
  652.         cmp    ax,EchoMax
  653.         ja    EchoSetMax
  654.   EchoCalcRet:
  655.         ret
  656.  
  657.   EchoSetMin:
  658.         mov    EchoMin,ax        ; minimum delay
  659.         jmp    short EchoChkMax
  660.   EchoSetMax:
  661.         mov    EchoMax,ax        ; maximum delay
  662.         ret
  663. EchoCalc    endp
  664.  
  665.  
  666.  
  667. ;************************************************************************
  668. ;*        HardwareTicks (48 bit time to si:dx:ax in 838 ns units)
  669. ;************************************************************************
  670.  
  671. TimerResolution equ    1193            ; hw ticks per millisecond
  672.  
  673. InitTimer    proc    near
  674.         test    ArgFlags,TIM_NOHIRES
  675.         jnz    InitTimRet
  676.         mov    dx,043h         ; select timer control port
  677.         mov    al,034h
  678.         out    dx,al            ; mode 2: Rate generator
  679.         call    IoDelay         ;   (counts down by 1 to zero)
  680.         xor    ax,ax
  681.         mov    dx,040h         ; select timer 0
  682.         out    dx,al            ; set divide by 2**16
  683.         call    IoDelay
  684.         out    dx,al            ; the generator is now started
  685.   InitTimRet:
  686.         ret
  687. InitTimer    endp
  688.  
  689. RestoreTimer    proc    near
  690.         test    ArgFlags,TIM_NOHIRES
  691.         jnz    ResTimRet
  692.         mov    dx,043h         ; select timer control port
  693.         mov    al,036h
  694.         out    dx,al            ; mode 3: Square wave generator
  695.         call    IoDelay         ;   (counts down by 2 to zero,
  696.         xor    ax,ax            ;    twice)
  697.         mov    dx,040h         ; select timer 0
  698.         out    dx,al            ; set divide by 2**16
  699.         call    IoDelay
  700.         out    dx,al
  701.   ResTimRet:
  702.         ret
  703. RestoreTimer    endp
  704.  
  705. IoDelay     proc    near
  706.         push    ax
  707.         in    al,061h
  708.         pop    ax
  709.         ret
  710. IoDelay     endp
  711.  
  712. HardwareTicks    proc    near
  713.         push    es
  714.         PushfDI
  715.         test    ArgFlags,TIM_NOHIRES
  716.         jnz    HwTicksNoHi
  717.  
  718.         mov    dx,020h         ;/* Address PIC ocw3   */
  719.         mov    al,00Ah         ;/* Ask to read irr    */
  720.         out    dx,al
  721.  
  722.         xor    al,al            ;/* Latch timer 0 */
  723.         out    043h,al
  724.         in    al,040h         ;/* Counter --> ax*/
  725.         mov    ah,al            ;/* LSB in AH      */
  726.         in    al,040h         ;/* MSB in AL      */
  727.         xchg    al,ah   
  728.         not    ax            ;/* Need ascending counter */
  729.         push    ax            ; Save hardware counter value
  730.  
  731.         in    al,dx            ;/* Read irr      */
  732.         push    ax            ; Save irr
  733.  
  734.         in    al,021h         ;/* Read PIC imr  */
  735.         push    ax            ; Save imr
  736.  
  737.         mov    al,00FFh        ;/* Mask all interrupts */
  738.         out    021h,al
  739.  
  740.         mov    ax,040h         ;/* read low word of time */
  741.         mov    es,ax            ;/* from BIOS data area   */
  742.         mov    dx,es:[06Ch]
  743.         mov    si,es:[06Ch+2]        ; get high word too
  744.  
  745.         pop    ax            ; Restore imr
  746.         out    021h,al
  747.         pop    ax            ; Restore irr
  748.         test    al,001h         ;/* Counter hit 0?    */
  749.                 pop     ax                      ; Restore counter value
  750.                 jnz     HwTicksMore             ;/* Jump if yes       */
  751.         popfEI
  752.         pop     es
  753.                 ret
  754.  
  755.   HwTicksMore:
  756.                 cmp     ax,0FFh                 ;/* Counter > 0x0FF?    */
  757.         ja    HwTicksDone        ;/* Done if so          */
  758.  
  759.         inc    dx            ;/* Else count int req. */
  760.   HwTicksDone:
  761.         popfEI
  762.         pop    es
  763.         ret
  764.  
  765.   HwTicksNoHi:
  766.         mov    ax,040h         ;/* read low word of time */
  767.         mov    es,ax            ;/* from BIOS data area   */
  768.         mov    dx,es:[06Ch]
  769.         mov    si,es:[06Ch+2]
  770.         xor    ax,ax
  771.         popfEI
  772.         pop    es
  773.         ret
  774. HardwareTicks    endp
  775.  
  776.  
  777.  
  778. ;========================================================================
  779. ;        endinclude
  780.